package com.zwps.biz.domain.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.zwps.biz.domain.converter.LogApiConverter;
import com.zwps.biz.domain.service.LogApiService;
import com.zwps.biz.api.model.dto.log.api.SelectLogApiDTO;
import com.zwps.biz.api.model.vo.log.api.SelectLogApiVO;
import com.zwps.biz.dal.db.dao.LogApiDAO;
import com.zwps.biz.dal.db.object.LogApiDO;
import com.zwps.common.api.model.vo.PageInfoVO;
import com.zwps.common.core.enums.LogTypeEnum;
import com.zwps.common.core.enums.OperateStatusEnum;
import com.zwps.common.core.enums.OperateTypeEnum;
import com.zwps.common.core.exception.UserActionException;
import com.zwps.common.core.service.CommonService;
import com.zwps.common.tool.enums.EnumConverter;
import com.zwps.extra.http.LogAPIMessage;

import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Service
@AllArgsConstructor
@Slf4j
public class LogApiServiceImpl implements LogApiService, CommonService {

    private LogApiDAO logApiDAO;

    private ObjectMapper objectMapper;

    @Override
    public void deleteLogApi(ArrayList<Integer> ids) {
        logApiDAO.deleteBatchIds(ids);
    }

    @Override
    public PageInfoVO<SelectLogApiVO> selectLogApiPage(SelectLogApiDTO dto) {
        PageHelper.startPage(dto.getPageNum(), dto.getPageSize());
        LambdaQueryWrapper<LogApiDO> query = new QueryWrapper<LogApiDO>().lambda();
        isNotEmptySetLike(query, LogApiDO::getOperateName, dto.getOperateName());
        isNotEmptySetLike(query, LogApiDO::getRequestUrl, dto.getRequestUrl());
        isNotEmptySetEq(query, LogApiDO::getRequestId, dto.getRequestId());
        isNotEmptySetEq(query, LogApiDO::getLogType, dto.getLogType());
        isNotEmptySetEq(query, LogApiDO::getOperateType, dto.getOperateType());
        isNotEmptySetEq(query, LogApiDO::getOperateUserId, dto.getOperateUserId());
        isNotEmptySetEq(query, LogApiDO::getOperateIp, dto.getOperateIp());
        isNotEmptySetEq(query, LogApiDO::getOperateStatus, dto.getOperateStatus());
        isNotEmptySetEq(query, LogApiDO::getRequestMethod, dto.getRequestMethod());
        isNotEmptySetLe(query, LogApiDO::getCreateTime, dto.getCreateTimeEnd());
        isNotEmptySetGe(query, LogApiDO::getCreateTime, dto.getCreateTimeStart());
        query.orderByDesc(LogApiDO::getId);
        List<LogApiDO> list = logApiDAO.selectList(query);

        Page<LogApiDO> page = (Page<LogApiDO>) list;
        ArrayList<SelectLogApiVO> voList = new ArrayList<>();
        PageInfoVO<SelectLogApiVO> pageInfo = new PageInfoVO<SelectLogApiVO>(page.getPageNum(), page.getPageSize(),
                page.getPages(), page.getTotal(), voList);

        for (LogApiDO logApiDO : list) {
            SelectLogApiVO vo = LogApiConverter.INSTANCE.toLogApiVO(logApiDO);
            LogTypeEnum logType = EnumConverter.conver(LogTypeEnum.values(), vo.getLogType());
            if (logType != null) {
                vo.setLogTypeName(logType.getName());
            }

            OperateTypeEnum operateType = EnumConverter.conver(OperateTypeEnum.values(), vo.getOperateType());
            if (operateType != null) {
                vo.setOperateTypeName(operateType.getName());
            }

            OperateStatusEnum operateStatus = EnumConverter.conver(OperateStatusEnum.values(), vo.getOperateStatus());
            if (operateStatus != null) {
                vo.setOperateStatusName(operateStatus.getName());
            }
            voList.add(vo);
        }
        return pageInfo;
    }

    @Override
    public void addLogApi(String message) {
        try {
            LogAPIMessage logMessage = objectMapper.readValue(message, LogAPIMessage.class);
            LogApiDO logApiDO = LogApiConverter.INSTANCE.toLogApiDO(logMessage);
            logApiDO.setCreateTime(LocalDateTime.now());
            if (logApiDAO.insert(logApiDO) < 1) {
                throw new UserActionException("新增接口日志失败");
            }
        } catch (Exception e) {
            log.error("Unexpected error in ", e);
        }
    }
}
